package com.n5x.service.impl;

import com.n5x.common.base.ResponseCode;
import com.n5x.common.weixinutils.WxPayUtil;
import com.n5x.mapper.goods.GoodsInfoMapper;
import com.n5x.mapper.shopping.*;
import com.n5x.mapper.user.UserDisCountMapper;
import com.n5x.mapper.user.UserInfoMapper;
import com.n5x.mapper.user.UserTransactionRecordMapper;
import com.n5x.model.AbstractModel;
import com.n5x.model.goods.GoodsInfo;
import com.n5x.model.shopping.*;
import com.n5x.model.user.UserDisCount;
import com.n5x.model.user.UserDisCountExample;
import com.n5x.model.user.UserInfo;
import com.n5x.model.user.UserTransactionRecord;
import com.n5x.service.IShoppingService;
import com.n5x.service.IUserService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.*;

/**
 * Created by Administrator on 2017/9/22.
 */
@Service
@Transactional
public class IShoppingServiceImpl implements IShoppingService {

    @Autowired
    private UserDisCountMapper userDisCountMapper;

    @Autowired
    private UserTransactionRecordMapper userTransactionRecordMapper;

    @Autowired
    private ShoppingCartMapper shoppingCartMapper;

    @Autowired
    private ShoppingOrderMapper shoppingOrderMapper;

    @Autowired
    private ShoppingOrderDetailsMapper shoppingOrderDetailsMapper;

    @Autowired
    private ShoppingOrderLogisticsMapper shoppingOrderLogisticsMapper;

    @Autowired
    private ShoppingOrderUserDisCountMapper shoppingOrderUserDisCountMapper;

    @Autowired
    private GoodsInfoMapper goodsInfoMapper;

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private IUserService iUserService;

    // ShoppingCart 购物车

    /**
     * 保存或更新购物车
     *
     * @param shoppingCart 购物车对象
     * @return 购物车ID
     */
    public void saveShoppingCart(ShoppingCart shoppingCart) {
        shoppingCart.setLastUpdateTime(new Date());
        if (StringUtils.isNotBlank(shoppingCart.getId())) {
            shoppingCartMapper.updateByPrimaryKeySelective(shoppingCart);
        } else {
            shoppingCart.init();
            shoppingCartMapper.insertSelective(shoppingCart);
        }
    }

    /**
     * 保存购物车
     *
     * @param userId           用户ID
     * @param shoppingCartList 购物车对象(主要包括商品ID，数量)
     */
    public void saveShoppingCart(String userId, List<ShoppingCart> shoppingCartList) {
        Assert.notNull(userId, "用户不能为空");
        Assert.notNull(shoppingCartList, "商品及商品数量不能为空");
        for (ShoppingCart sc : shoppingCartList) {
            String fkGoods = sc.getFkGoods();
            int qty = sc.getQty();
            ShoppingCart cart = this.findShoppingCart(userId, fkGoods);
            if (cart == null) {
                cart = new ShoppingCart(fkGoods);
            }
            cart.setFkUser(userId);
            cart.setQty(cart.getQty() + qty);
            this.saveShoppingCart(cart);
        }
    }

    /**
     * 删除购物车
     *
     * @param id 购物车ID
     * @return 更新数据库记录数
     */
    public int deleteShoppingCart(String id) {
        return shoppingCartMapper.deleteByPrimaryKey(id);
    }

    /**
     * 根据用户查找购物车
     *
     * @param userId 用户ID
     * @return 购物车列表
     */
    public List<ShoppingCart> findShoppingCartByUser(String userId) {
        Assert.notNull(userId, "用户ID不能为空");
        ShoppingCartExample shoppingCartExample = new ShoppingCartExample();
        shoppingCartExample.or().andFkUserEqualTo(userId).andDisableEqualTo(Boolean.FALSE);
        shoppingCartExample.setOrderByClause(AbstractModel.ORDER);
        return shoppingCartMapper.selectByExample(shoppingCartExample);
    }

    /**
     * 查找购物车
     *
     * @param id 购物车ID
     * @return 购物车对象
     */
    public ShoppingCart findShoppingCart(String id) {
        Assert.notNull(id, "购物车ID不能为空");
        return shoppingCartMapper.selectByPrimaryKey(id);
    }

    /**
     * 根据用户及商品查找对应购物车
     *
     * @param userId  用户ID
     * @param goodsId 商品ID
     * @return 购物车对象, 没有为null
     */
    public ShoppingCart findShoppingCart(String userId, String goodsId) {
        Assert.notNull(userId, "用户ID不能为空");
        Assert.notNull(goodsId, "商品ID不能为空");
        ShoppingCartExample shoppingCartExample = new ShoppingCartExample();
        shoppingCartExample.or().andFkUserEqualTo(userId).andFkGoodsEqualTo(goodsId).andDisableEqualTo(Boolean.FALSE);
        List<ShoppingCart> list = shoppingCartMapper.selectByExample(shoppingCartExample);
        if (CollectionUtils.isNotEmpty(list)) return list.iterator().next();
        return null;
    }

    //ShoppingOrder 订单
    public ShoppingOrder saveNewShoppingOrderByGoods(String userId, List<ShoppingOrderDetails> orderDetails) {
        Assert.notNull(userId, "用户ID不能为空");
        Assert.notNull(orderDetails, "订单明细不能为空");
        //生成订单
        ShoppingOrder shoppingOrder = new ShoppingOrder(userId, ShoppingOrder.ShoppingOrderType.商品订单);
        shoppingOrder.init();
        shoppingOrder.setReceiptCode(new Date().getTime() + "");
        shoppingOrderMapper.insert(shoppingOrder);
        //生成订单明细
        for (ShoppingOrderDetails shoppingOrderDetails : orderDetails) {
            shoppingOrderDetails.setFkShoppingOrder(shoppingOrder.getId());
            shoppingOrderDetails.init();
            shoppingOrderDetailsMapper.insert(shoppingOrderDetails);
        }
        return shoppingOrder;
    }

    /**
     * 保存订单信息及用户优惠信息
     *
     * @param shoppingOrder   订单
     * @param userDiscountIds 用户优惠券ID
     * @return 订单信息
     */
    public ShoppingOrder saveShoppingOrder(ShoppingOrder shoppingOrder, String[] userDiscountIds) {
        Assert.notNull(shoppingOrder, "订单不能为空");
        if (ArrayUtils.isEmpty(userDiscountIds)) {
            shoppingOrderMapper.updateByPrimaryKeySelective(shoppingOrder);
            return shoppingOrder;
        }
        List<String> userDiscountIdList = Arrays.asList(userDiscountIds);
        UserDisCountExample userDisCountExample = new UserDisCountExample();
        userDisCountExample.or().andIdIn(userDiscountIdList).andDiscountVaildTimeLessThanOrEqualTo(new Date()).andDiscountTypeEqualTo(UserDisCount.DiscountType.现金优惠.name()).andFkUserEqualTo(shoppingOrder.getFkUser());
        List<UserDisCount> userDisCountList = userDisCountMapper.selectByExampleWithBLOBs(userDisCountExample);
        //删除优惠券
        for (UserDisCount userDisCount : userDisCountList) {
            userDisCount.setDisable(Boolean.TRUE);
            userDisCount.setLastUpdateTime(new Date());
            userDisCount.setUseTime(new Date());
            userDisCountMapper.updateByPrimaryKeySelective(userDisCount);
            ShoppingOrderUserDisCount shoppingOrderUserDisCount = new ShoppingOrderUserDisCount(shoppingOrder.getId(), userDisCount.getId());
            //添加优惠券跟商品绑定关系
            shoppingOrderUserDisCountMapper.insert(shoppingOrderUserDisCount);
        }
        shoppingOrder.settingUserDiscount(userDisCountList);
        shoppingOrderMapper.updateByPrimaryKeySelective(shoppingOrder);
        return shoppingOrder;
    }

    public Map<String, Object> saveShoppingOrderByPay(ShoppingOrder shoppingOrder, String userId) throws Exception {
        if (!shoppingOrder.getCurrentState().equals(ShoppingOrder.ShoppingState.未付款.getState())) {
            Map<String, Object> result = new HashMap<String, Object>();
            result.put(ResponseCode.Common_ParamError, "订单重复提交");
            return result;
        }
        UserInfo userInfo = userInfoMapper.selectByPrimaryKey(userId);
        //微信支付
        if (shoppingOrder.getTransactionMethod().equals(ShoppingOrder.TransactionMethod.微信.getMethod())) {
            UserTransactionRecord userTransactionRecord = userTransactionRecordMapper.selectByPrimaryKey(shoppingOrder.getTransactionNumber());
            if (userTransactionRecord == null) {
                Map<String, Object> result = new HashMap<String, Object>();
                result.put(ResponseCode.Common_ParamError, "交易记录为空");
                return result;
            }
            Thread.sleep(1000);
            Map map = WxPayUtil.queryOrder(userTransactionRecord.getTransactionNumber());
            String tradeState = (String) map.get("tradeState");
            BigDecimal money = new BigDecimal((String) map.get("totalfee"));
            boolean flag = tradeState.equals(WxPayUtil.PayState.支付成功.getState()) && money.compareTo(userTransactionRecord.getMoney().multiply(new BigDecimal(100))) == 0 && money.compareTo(shoppingOrder.getTotalMoney().multiply(new BigDecimal(100))) == 0 && userTransactionRecord.getDisable() == Boolean.TRUE;
            if (!flag) {
                Map<String, Object> result = new HashMap<String, Object>();
                result.put(ResponseCode.Common_ParamError, "交易失败");
                return result;
            }
            userTransactionRecord.setDisable(Boolean.FALSE);
            if (StringUtils.isBlank(userTransactionRecord.getFkUser())) {
                userTransactionRecord.setFkUser(userId);
            }
            userTransactionRecordMapper.updateByPrimaryKey(userTransactionRecord);
        }
        //余额支付
        if (shoppingOrder.getTransactionMethod().equals(ShoppingOrder.TransactionMethod.余额.getMethod())) {
            BigDecimal balance = userInfo.getBalance().subtract(shoppingOrder.getTotalMoney());
            if (!(balance.intValue() >= 0)) {
                Map<String, Object> result = new HashMap<String, Object>();
                result.put(ResponseCode.Common_ParamError, "用户余额不足");
                return result;
            }
            userInfo.setBalance(balance);
            userInfoMapper.updateByPrimaryKeySelective(userInfo);
            UserTransactionRecord userTransactionRecord = new UserTransactionRecord(userId, shoppingOrder.getReceiptCode(), UserTransactionRecord.Method.余额, UserTransactionRecord.TransactionType.消费, shoppingOrder.getTotalMoney());
            userTransactionRecord.setDisable(Boolean.FALSE);
            userTransactionRecordMapper.insert(userTransactionRecord);
        }
        //推荐人赠送
        /*
        JSONObject jsonObject = userInfo.getRecommendJSON();
        if (jsonObject != null && !jsonObject.isNullObject()) {
            String isDiscountStr = jsonObject.getString(UserInfo.RECOMMEND_IS_DISCOUNT);
            if ("0".equals(isDiscountStr)) {
                String phone = jsonObject.getString(UserInfo.RECOMMEND_PHONE);
                UserInfo recommend = iUserService.findUserInfoByLogin(phone);
                recommend.setBalance(recommend.getBalance().add(new BigDecimal(5)));
                recommend.setFkLevel("1");
                userInfoMapper.updateByPrimaryKeySelective(recommend);
                UserTransactionRecord recommendTransactionRecord = new UserTransactionRecord(recommend.getId(), shoppingOrder.getReceiptCode(), UserTransactionRecord.Method.余额, UserTransactionRecord.TransactionType.赠送, new BigDecimal(5)).setNote("推荐优惠");
                recommendTransactionRecord.setDisable(Boolean.FALSE);
                userTransactionRecordMapper.insert(recommendTransactionRecord);
                jsonObject.put(UserInfo.RECOMMEND_IS_DISCOUNT,"1");
                userInfo.setRecommend(jsonObject.toString());
                userInfoMapper.updateByPrimaryKeySelective(userInfo);
            }
        }
        */
        // 商品库存
        ShoppingOrderDetailsExample shoppingOrderDetailsExample = new ShoppingOrderDetailsExample();
        shoppingOrderDetailsExample.createCriteria().andFkShoppingOrderEqualTo(shoppingOrder.getId()).andDisableEqualTo(Boolean.FALSE);
        List<ShoppingOrderDetails> detailsList = shoppingOrderDetailsMapper.selectByExample(shoppingOrderDetailsExample);
        for (ShoppingOrderDetails details : detailsList) {
            String goodsId = details.getFkSourceId();
            GoodsInfo goodsInfo = goodsInfoMapper.selectByPrimaryKey(goodsId);
            goodsInfo.setQty(goodsInfo.getQty() - details.getQty());
            goodsInfoMapper.updateByPrimaryKeySelective(goodsInfo);
        }
        // 更新订单状态
        shoppingOrder.setCurrentState(ShoppingOrder.ShoppingState.已付款.getState());
        shoppingOrder.setPayTime(new Date());
        shoppingOrderMapper.updateByPrimaryKeySelective(shoppingOrder);
        return null;
    }

    /**
     * 添加订单物流信息，如果有交易记录新增交易，如果订单完成更新订单办结时间
     *
     * @param shoppingOrder          订单信息
     * @param shoppingOrderLogistics 物流信息
     * @param userTransactionRecord  交易记录
     * @return 订单信息
     */
    public ShoppingOrder saveShoppingOrder(ShoppingOrder shoppingOrder, ShoppingOrderLogistics shoppingOrderLogistics, UserTransactionRecord userTransactionRecord) {
        Assert.notNull(shoppingOrder, "订单不能为空");
        Assert.notNull(shoppingOrderLogistics, "物流信息不能为空");
        //保存用户交易记录
        if (userTransactionRecord != null) {
            userTransactionRecord.init();
            userTransactionRecordMapper.insertSelective(userTransactionRecord);
            shoppingOrderLogistics.settingTransaction(userTransactionRecord.getId(), userTransactionRecord.getNote().getBytes());
        }
        //保存用户物流记录及物流金额
        shoppingOrderLogistics.init();
        shoppingOrderLogisticsMapper.insert(shoppingOrderLogistics);
        shoppingOrder.setCurrentState(shoppingOrderLogistics.getState());
        //交易完成或交易作废保存办结时间
        if (shoppingOrderLogistics.getState().equals(ShoppingOrderLogistics.LogisticsState.交易完成.name())) {
            shoppingOrder.setFinishTime(shoppingOrderLogistics.getLogisticsTime());
        }
        if (shoppingOrderLogistics.getState().equals(ShoppingOrderLogistics.LogisticsState.交易作废.name())) {
            shoppingOrder.setFinishTime(shoppingOrderLogistics.getLogisticsTime());
        }
        shoppingOrderMapper.updateByPrimaryKeySelective(shoppingOrder);
        return shoppingOrder;
    }

    /**
     * 根据订单ID查找订单
     *
     * @param orderId 订单ID
     * @return 订单对象
     */
    public ShoppingOrder findShoppingOrder(String orderId) {
        Assert.notNull(orderId, "订单ID不能为空");
        return shoppingOrderMapper.selectByPrimaryKey(orderId);
    }

    /**
     * 查询订单列表
     *
     * @param criteria 查询条件
     * @return 订单列表
     */
    public List<ShoppingOrder> findShoppingOrderList(ShoppingOrderExample.Criteria criteria) {
        ShoppingOrderExample shoppingOrderExample = new ShoppingOrderExample();
        if (criteria == null) {
            criteria = shoppingOrderExample.or();
        } else {
            shoppingOrderExample.or(criteria);
        }
        shoppingOrderExample.setOrderByClause(AbstractModel.ORDER);
        return shoppingOrderMapper.selectByExample(shoppingOrderExample);
    }

    // 订单明细 ShoppingOrderDetails

    /**
     * 查询订单明细
     *
     * @param shoppingOrderId 订单ID
     * @return 订单明细列表
     */
    public List<ShoppingOrderDetails> findShoppingOrderDetails(String shoppingOrderId) {
        Assert.notNull(shoppingOrderId, "订单ID不能为空");
        ShoppingOrderDetailsExample shoppingOrderDetailsExample = new ShoppingOrderDetailsExample();
        shoppingOrderDetailsExample.or().andDisableEqualTo(Boolean.FALSE).andFkShoppingOrderEqualTo(shoppingOrderId);
        shoppingOrderDetailsExample.setOrderByClause(AbstractModel.ORDER);
        return shoppingOrderDetailsMapper.selectByExample(shoppingOrderDetailsExample);
    }

    public List<ShoppingOrder> selectUserShopingOrder(Map map) {
        return shoppingOrderMapper.selectUserShopingOrder(map);
    }

    public int countUserShopingOrder(Map map) {
        return shoppingOrderMapper.countUserShopingOrder(map);
    }
}